home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / BPNN133U.ZIP / NNTRAIN.C < prev    next >
C/C++ Source or Header  |  1992-11-19  |  9KB  |  420 lines

  1. /*
  2. *-----------------------------------------------------------------------------
  3. *    file:    nntrain.c
  4. *    desc:    train a fully connected neural net by backpropagation
  5. *    by:    patrick ko
  6. *    date:    2 aug 91
  7. *    revi:    v1.2b - 15 jan 92, adaptive coefficients
  8. *        v1.3u - 18 jan 92, revised data structures
  9. *        v1.31u - 20 jan 92, periodic dump, weights retrieval
  10. *-----------------------------------------------------------------------------
  11. */
  12. #include <stdio.h>
  13. #include <math.h>
  14. #include <values.h>
  15. #include <time.h>
  16.  
  17. #include "nntype.h"
  18. #include "nnmath.h"
  19. #include "nntrain.h"
  20. #include "nndump.h"
  21.  
  22. #define    global
  23. #define    LAMBDA0    0.1
  24.  
  25. static REAL    ETA = ETA_DEFAULT;
  26. static REAL    MOMENTUM = ALPHA_DEFAULT;
  27. static REAL    LAMBDA = LAMBDA_DEFAULT;
  28. static INTEGER    REPINTERVAL = 0;
  29. global REAL    TOLER = TOLER_DEFAULT;
  30.  
  31. /*
  32. *=============================================================================
  33. *    funct:    nnbp_train
  34. *    dscpt:    train a neural net using backpropagation
  35. *    given:    net = the neural net
  36. *        inpvect = 1 input vector ( 1 train pattern )
  37. *        tarvect = 1 target vector ( 1 target pattern )
  38. *        np = number of patterns
  39. *        err = error
  40. *        eta, momentum
  41. *        report = dump info interval (no.of train cycles), 0=not dump
  42. *        tdump = no of seconds for periodic dump, 0=not dump
  43. *        dfilename = period dump file name
  44. *    retrn:    measure of error
  45. *=============================================================================
  46. */
  47. REAL nnbp_train( net, inpvect, tarvect, np, err, eta, momentum, report, tdump, dfilename )
  48. NET    *net;
  49. VECTOR    **inpvect;
  50. VECTOR    **tarvect;
  51. REAL    err, eta, momentum;
  52. INTEGER    np, report;
  53. long int tdump;
  54. char    *dfilename;
  55. {
  56.     REAL    Error;
  57.     INTEGER    cnt;
  58.     time_t    lasttime, thistime;
  59.     FILE    *fdump;
  60.  
  61.  
  62.     cnt = 0;
  63.     REPINTERVAL = report;
  64.     ETA = eta;
  65.     MOMENTUM = momentum;
  66.     Error = MAXFLOAT;
  67.     if (tdump)
  68.         time(&lasttime);
  69.  
  70.     while (Error > err)
  71.         {
  72.         cnt++;
  73.         Error = nnbp_train1( net, inpvect, tarvect, np, Error );
  74.  
  75.         if (report)
  76.             nnbp_report(cnt, Error);
  77.         if (tdump)
  78.             {
  79.             if (((thistime = time(&thistime)) - lasttime) >= tdump)
  80.                 {
  81.                 fdump = fopen( dfilename, "w" );
  82.                 nn_dump( fdump, net );
  83.                 fclose(fdump);
  84.                 lasttime = thistime;
  85.                 }
  86.             }
  87.         }
  88.     return (Error);
  89. }
  90.  
  91. /*
  92. *=============================================================================
  93. *    funct:    nnbp_report
  94. *    dscpt:    print report lines to terminal
  95. *    given:    cnt = number of train cycles
  96. *        error = overall energy
  97. *    retrn:    nothing
  98. *=============================================================================
  99. */
  100. void nnbp_report( cnt, error )
  101. INTEGER    cnt;
  102. REAL    error;
  103. {
  104.     if (!(cnt%REPINTERVAL))
  105.         {
  106.         printf("nntrain: cycle= %d, MSE/Unit =%f\n", cnt, error );
  107.         fflush(stdout);
  108.         }
  109. }
  110.  
  111. /*
  112. *=============================================================================
  113. *    funct:    nnbp_train1
  114. *    dscpt:    train a neural net 1 cycle using backpropagation
  115. *    given:    net = the neural net
  116. *        inpvect = 1 set of input vectors
  117. *        tarvect = 1 set of target vectors
  118. *        np = number of patterns
  119. *        LastError = energy at last cycle
  120. *    retrn:    measure of error after this train cycle
  121. *=============================================================================
  122. */
  123. REAL nnbp_train1( net, inpvect, tarvect, np, LastError )
  124. NET    *net;
  125. VECTOR    **inpvect;
  126. VECTOR     **tarvect;
  127. INTEGER    np;
  128. REAL    LastError;
  129. {
  130.     REAL    Error;
  131.     INTEGER    i;
  132.     INTEGER    fire=0;
  133.  
  134.     Error = 0.0;
  135.     nnbp_init( net );
  136.     for (i=0; i<np; i++)
  137.         {
  138.         nnbp_forward( net, *(inpvect + i));
  139.         Error += nnbp_backward( net, *(inpvect + i), *(tarvect + i));
  140.         }
  141.     Error = Error / np / DimNetOut(net);
  142.     /*
  143.     * coefficients adaptation and dWeight calculations
  144.     */
  145.     if (Error <= LastError + TOLER )
  146.         {
  147.  
  148.         /* weights will be updated, go ahead */
  149.  
  150.         fire = 1;
  151.         nnbp_coeffadapt( net );
  152.         nnbp_dweightcalc( net, np, fire );
  153.         return (Error);
  154.         }
  155.     else
  156.         {
  157.  
  158.         /* weights will not be updated, backtrack */
  159.  
  160.         fire = 0;
  161.         ETA *= BACKTRACK_STEP;        /* half the ETA */
  162.         ETA = ground(ETA,ETA_FLOOR);
  163.         MOMENTUM = ETA * LAMBDA;
  164.         nnbp_dweightcalc( net, np, fire );
  165.         return (LastError);
  166.         }
  167. }
  168.  
  169. /*
  170. *=============================================================================
  171. *    funct:    nnbp_forward (pass)
  172. *    dscpt:    forward pass calculation
  173. *    given:    net = the neural net
  174. *        inpvect = 1 input vector ( 1 train pattern )
  175. *    retrn:    nothing
  176. *    cmmnt:    net's output Out(J) calculated at every unit
  177. *=============================================================================
  178. */
  179. void nnbp_forward( net, inpvect )
  180. NET    *net;
  181. VECTOR    *inpvect;
  182. {
  183.     LAYER    *I, *input;
  184.     UNIT    *J;
  185.     INTEGER    i, j, k;
  186.     REAL    sum, out;
  187.  
  188.     /* phase 1 - forward compute output value Out's */
  189.  
  190.     input = NULL;
  191.  
  192.     /* For each layer I in the network */
  193.  
  194.     for (i=0; i<DimNet(net); i++)
  195.         {
  196.         I = Layer(net,i);
  197.  
  198.         /* For each unit J in the layer */
  199.  
  200.         for (j=0; j<DimLayer(I); j++)
  201.             {
  202.             J = Unit(I,j);
  203.             Net(J) = Bias(J) + dBias1(J); /* add bias */
  204.             for (k=0; k<DimvWeight(J); k++)
  205.                 {
  206.                 if (i==0)
  207.                     out = Vi(inpvect,k);
  208.                 else
  209.                     out = Out(Unit(input,k));
  210.  
  211.                 Net(J) += (Weight(J,k) + dWeight1(J,k)) * out;
  212.                 }
  213.             Out(J) = sigmoid(Net(J));
  214.             }
  215.         input = I;
  216.         }
  217. }
  218.  
  219.  
  220. void nnbp_init( net )
  221. NET    *net;
  222. {
  223.     LAYER    *I;
  224.     UNIT    *J;
  225.     INTEGER    i, j, k;
  226.  
  227.     i = DimNet(net);
  228.  
  229.     while (i--)
  230.         {
  231.         I = Layer(net,i);
  232.         for (j=0; j<DimLayer(I); j++)
  233.             {
  234.             J = Unit(I,j);
  235.             nDlt(J) = 0.0;
  236.             for (k=0; k<DimvWeight(J); k++)
  237.                 {
  238.                 DO(J,k) = 0.0;
  239.                 }
  240.             }
  241.         }
  242. }
  243.  
  244. /*
  245. *=============================================================================
  246. *    funct:    nnbp_backward
  247. *    dscpt:    backward pass calculation
  248. *    given:    net = the neural net
  249. *        inpvect = 1 input vector ( 1 train pattern )
  250. *        tarvect = 1 target vector
  251. *    retrn:    Ep * 2
  252. *    cmmnt:    net's weight and bias adjusted at every layer
  253. *=============================================================================
  254. */
  255. REAL nnbp_backward( net, inpvect, tarvect )
  256. NET    *net;
  257. VECTOR    *inpvect;
  258. VECTOR    *tarvect;
  259. {
  260.     LAYER    *I, *F, *B;
  261.     UNIT    *J, *JF;
  262.     INTEGER    i, j, k;
  263.     REAL    sum, out;
  264.     REAL    Ep, diff;
  265.  
  266.     Ep = 0.0;
  267.  
  268.     /*
  269.     *    phase 2 - target comparison and back propagation
  270.     */
  271.     i = DimNet(net) - 1;
  272.     F = I = Layer(net,i);
  273.     B = Layer(net,i - 1);
  274.  
  275.     /*
  276.     *    Delta rule 1 - OUTPUT LAYER
  277.     *    dpj = (tpj - opj) * f'(netpj)
  278.     */
  279.     for (j=0; j<DimLayer(I); j++)
  280.         {
  281.         J = Unit(I,j);
  282.         diff = Vi(tarvect,j) - Out(J);
  283.         Dlt(J) = diff * Out(J) * (1.0 - Out(J));
  284.  
  285.         nDlt(J) += Dlt(J);    /* accumulate Dpj's */
  286.  
  287.         for (k=0; k<DimvWeight(J); k++)
  288.             {
  289.             if (i==0)
  290.                 out = Vi(inpvect,k);
  291.             else
  292.                 out = Out(Unit(B,k));
  293.             DO(J,k) += Dlt(J) * out;
  294.             }
  295.  
  296.         Ep += diff * diff;
  297.         }
  298.  
  299.     --i;
  300.     while (i >= 0)
  301.         {
  302.         I = Layer(net,i);        /* current layer */
  303.         B = Layer(net,i - 1);
  304.         /*
  305.         *    delta rule 2 - HIDDEN LAYER:
  306.         *    dpj = f'(netpj) * SUMMATEk( Dpk * Wkj )
  307.         */
  308.         for (j=0; j<DimLayer(I); j++)
  309.             {
  310.             J = Unit(I,j);
  311.             sum = 0.0;
  312.             for (k=0; k<DimLayer(F); k++)
  313.                 {
  314.                 JF = Unit(F,k);
  315.                 sum += Dlt(JF) * (Weight(JF,j)+dWeight1(JF,j));
  316.                 }
  317.             Dlt(J) = Out(J) * (1.0 - Out(J)) * sum;
  318.             nDlt(J) += Dlt(J);
  319.  
  320.             for (k=0; k<DimvWeight(J); k++)
  321.                 {
  322.                 if (i==0)
  323.                     out = Vi(inpvect,k);
  324.                 else
  325.                     out = Out(Unit(B,k));
  326.                 DO(J,k) += Dlt(J) * out;
  327.                 }
  328.             }
  329.         F = I;
  330.         i--;
  331.         }
  332.  
  333.     return (Ep);
  334. }
  335.  
  336. void nnbp_coeffadapt( net )
  337. NET    *net;
  338. {
  339.     LAYER    *I, *B;
  340.     UNIT    *J;
  341.     INTEGER    n, i, j, k;
  342.     REAL    EW, ME, MW, costh;
  343.  
  344.     EW = ME = MW = 0.0;
  345.     i = DimNet(net);
  346.  
  347.     while (i--)
  348.         {
  349.         I = Layer(net,i);
  350.         for (j=0; j<DimLayer(I); j++)
  351.             {
  352.             J = Unit(I,j);
  353.             for (k=0; k<DimvWeight(J); k++)
  354.                 {
  355.                 ME += DO(J,k) * DO(J,k);
  356.                 MW += dWeight1(J,k) * dWeight1(J,k);
  357.                 EW += DO(J,k) * dWeight1(J,k);
  358.                 }
  359.             }
  360.         }
  361.  
  362.     ME = sqrt(ME);        /* modulus of cost funct vector E */
  363.     MW = sqrt(MW);        /* modulus of delta weight vector dWn-1*/
  364.  
  365.     ME = ground(ME,ME_FLOOR);        /* constraints */
  366.     MW = ground(MW,MW_FLOOR);        /* constraints */
  367.  
  368.     costh = EW / (ME * MW);
  369.  
  370.     /* coefficients adaptation !!! */
  371.  
  372.     ETA = ETA * (1.0 + 0.5 * costh);
  373.     ETA = ground(ETA,ETA_FLOOR);
  374.     LAMBDA = LAMBDA0 * ME / MW;
  375.     MOMENTUM = ETA * LAMBDA;
  376. }
  377.  
  378. void nnbp_dweightcalc( net, np, fire )
  379. NET    *net;
  380. INTEGER    np;
  381. INTEGER    fire;
  382. {
  383.     LAYER    *I;
  384.     UNIT    *J;
  385.     INTEGER    n, i, j, k;
  386.  
  387.     i = DimNet(net);
  388.  
  389.     /* calculate dWeights for every unit */
  390.  
  391.     while (i--)
  392.         {
  393.         I = Layer(net,i);
  394.         for (j=0; j<DimLayer(I); j++)
  395.             {
  396.             J = Unit(I,j);
  397.             nDlt(J) /= np;
  398.             for (k=0; k<DimvWeight(J); k++)
  399.                 {
  400.                 DO(J,k) /= np;
  401.                 if (fire)
  402.                     {
  403.                     /* commit weight change */
  404.                     Weight(J,k) += dWeight1(J,k);
  405.  
  406.                     /* dW n-2 = dW n-1 */
  407.                     dWeight2(J,k) = dWeight1(J,k);
  408.                     }
  409.                 dWeight1(J,k) = ETA * DO(J,k) + MOMENTUM * dWeight2(J,k);
  410.                 }
  411.             if (fire)
  412.                 {
  413.                 Bias(J) += dBias1(J);
  414.                 dBias2(J) = dBias1(J);
  415.                 }
  416.             dBias1(J) = ETA * nDlt(J) + MOMENTUM * dBias2(J);
  417.             }
  418.         }
  419. }
  420.